#include "Almacenamiento.h"

namespace Toolkit
{

Almacenamiento::Almacenamiento(const unsigned long int &tamanoUnidad,
		 const TipoSerializacion &tserializacion)
{
	this-> tamanoUnidad = tamanoUnidad;
	this-> tserializacion = tserializacion;
	elementos = 0;
}

Almacenamiento::Almacenamiento(const TipoSerializacion &tserializacion)
{
	this-> tserializacion = tserializacion;
}

Almacenamiento::~Almacenamiento() 
{	
}

unsigned long int Almacenamiento::guardarDato (const stringstream &serializacion)
{	
	elementos++;
	guardarDato(serializacion, elementos - 1);
	
	return elementos - 1;
}

void Almacenamiento::guardarDato(const stringstream &serializacion, const unsigned long int posicion)
{
	string datos = serializacion.str();	
	if (datos.size() > getTamano()) {
		throw SerializacionInvalidaException();
	} else if (posicion >= elementos) {
		throw PosicionInvalidaException();
	} else {
		int libres = getTamano() - datos.size();
		
		if (libres > 0) {
			datos.append(libres, '#');
		}
	}	
	stream->seekg(posicion * getTamano() + offsetElementos, ios_base::beg);	
	stream->write(datos.c_str(), getTamano());
	
}

void Almacenamiento::recuperarDato(const unsigned long int posicion, stringstream &resultado) const
{
	if (posicion >= elementos) {
		throw PosicionInvalidaException();
	}
	
	stream->seekg(posicion * getTamano() + offsetElementos, ios_base::beg);
	
	char informacion[getTamano()];
	stream->read(informacion, getTamano());
	
	string sInformacion(informacion);
	size_t relleno = sInformacion.find_first_of("#");
	if (relleno != string::npos) {
		sInformacion.erase(relleno, sInformacion.size() - relleno);	
	}
	
	resultado.str("");
	resultado.write(sInformacion.c_str(), getTamano());	
}

void Almacenamiento::eliminarDato (unsigned const long int posicion, stringstream &resultado)
{
	recuperarDato(posicion, resultado);
}

unsigned long int Almacenamiento::getTamano () const
{	
	return tamanoUnidad;
}

unsigned long int Almacenamiento::cantElementos() const
{
	return elementos;
}



}
